package org.bobo.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.bobo.bean.CollectDO;
import org.bobo.bean.CommentDO;
import org.bobo.bean.CommentLikeRecordDO;
import org.bobo.bean.UserDO;
import org.bobo.common.constant.enums.ExceptionEnums;
import org.bobo.common.exception.BusinessException;
import org.bobo.common.util.IPUtils;
import org.bobo.common.util.bobo.IpUtil;
import org.bobo.common.util.oConvertUtils;
import org.bobo.dto.CommentDTO;
import org.bobo.mapper.CommentDOMapper;
import org.bobo.service.ICommentDOService;
import org.bobo.service.ICommentLikeRecordDOService;
import org.bobo.service.IUserDOService;
import org.bobo.vo.CommentVO;
import org.bobo.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @Description: 文章评论管理
 * @Author: bobo
 * @Date: 2022-02-27
 * @Version: V1.0
 */
@Service
public class CommentDOServiceImpl extends ServiceImpl<CommentDOMapper, CommentDO> implements ICommentDOService {

    @Autowired
    private ICommentLikeRecordDOService commentLikeRecordDOService;

    @Autowired
    private IUserDOService userDOService;
    /**
     * 评论
     *
     * @param commentDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public CommentVO comment(CommentDTO commentDTO) {
        CommentDO commentDO = new CommentDO();
        BeanUtil.copyProperties(commentDTO, commentDO);

        //ip地址转所属区域
        commentDO.setAddress(IpUtil.getAddress(commentDO.getIp()));

        UserDO userDO = (UserDO) SecurityUtils.getSubject().getPrincipal();
        commentDO.setUserId(userDO.getId());
        if (oConvertUtils.isNotEmpty(commentDO.getParentId())) {//说明是回复一级或者二级评论
            //判断参数合法性
            CommentDO parentComment = baseMapper.selectById(commentDO.getParentId());
            if (parentComment == null) {
                throw new BusinessException(ExceptionEnums.PARAM_ILLEGAL);
            }
            //如果reply存在且不等于parentId说明回复的是二级评论 要检查二级评论是否存在，否则说明回复一级评论，一级评论是否存在上面已经判断了（baseMapper.selectById(commentDO.getParentId());）
            if (oConvertUtils.isNotEmpty(commentDTO.getReply()) && !commentDTO.getReply().equals(commentDO.getParentId())) {
                CommentDO replyTo = baseMapper.selectOne(new LambdaQueryWrapper<CommentDO>().eq(CommentDO::getParentId, commentDO.getParentId()).eq(CommentDO::getId, commentDO.getReply()).last("limit 1"));
                if (replyTo == null) {
                    throw new BusinessException(ExceptionEnums.PARAM_ILLEGAL);
                } else {
                    commentDO.setReplyWho(replyTo.getUserId());
                }
                //对评论表回复数作出递增操作
                if(baseMapper.incrReply(commentDTO.getReply())<1){
                    throw new BusinessException(ExceptionEnums.SYSTEM_ERROR);
                }
                //对评论表回复数作出递增操作
                if(baseMapper.incrReply(commentDTO.getParentId())<1){
                    throw new BusinessException(ExceptionEnums.SYSTEM_ERROR);
                }
            } else {
                commentDO.setReplyWho(parentComment.getUserId());
                //对评论表回复数作出递增操作
                if(baseMapper.incrReply(commentDTO.getReply())<1){
                    throw new BusinessException(ExceptionEnums.SYSTEM_ERROR);
                }
            }


        } else if (oConvertUtils.isEmpty(commentDO.getParentId()) && oConvertUtils.isNotEmpty(commentDO.getReply())) {//如果parentId为空而reply不为空参数不合法
            throw new BusinessException(ExceptionEnums.PARAM_ILLEGAL);
        }

        if(baseMapper.insert(commentDO)<1){
            throw new BusinessException(ExceptionEnums.SYSTEM_ERROR);
        }

        CommentVO commentVO =new CommentVO();
        UserVO userVO =new UserVO();
        //前端需要立马回显
        BeanUtil.copyProperties(commentDO,commentVO);
        BeanUtil.copyProperties(userDO,userVO);
        commentVO.setCommentWho(userVO);
        commentVO.setMyLike(false);
        commentVO.setLikeNum(0);
        commentVO.setReplyCount(0);
        if(oConvertUtils.isNotEmpty(commentDTO.getReply())){
            UserVO replyWho =new UserVO();
            UserDO  replyWhoDO= userDOService.getById(commentDO.getReplyWho());
            BeanUtil.copyProperties(replyWhoDO,replyWho);
            commentVO.setReplyWho(replyWho);
        }
        return commentVO;
    }
    /**
     * 自定义分页查询
     * @param page 分页
     * @param type 类型 video gags
     * @param sourceId 视频源id
     * @param parentId 父评论id
     * @return
     */
    @Override
    public IPage<CommentVO> customPage(Page<CommentDO> page, String type, Long sourceId, Long parentId,String sort) {
        UserDO userDO = (UserDO) SecurityUtils.getSubject().getPrincipal();

        LambdaQueryWrapper<CommentDO> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(oConvertUtils.isNotEmpty(type),CommentDO::getType,type);
        lambdaQueryWrapper.eq(oConvertUtils.isNotEmpty(sourceId),CommentDO::getSourceId,sourceId);
        lambdaQueryWrapper.eq(oConvertUtils.isNotEmpty(parentId),CommentDO::getParentId,parentId);
        lambdaQueryWrapper.isNull(oConvertUtils.isEmpty(parentId),CommentDO::getParentId);
        IPage<CommentVO> retPage= baseMapper.customPage(page, lambdaQueryWrapper,sort);
        retPage.getRecords().forEach(item ->{
            if(commentLikeRecordDOService.getByUserIdCommentId(item.getId(),userDO.getId())!=null){
                item.setMyLike(true);
            }
        });
        return retPage;
    }
    /**
     * 自定义分页查询 不需要认证
     * @param page 分页
     * @param type 类型 video gags
     * @param sourceId 视频源id
     * @param parentId 父评论id
     * @return
     */
    @Override
    public IPage<CommentVO> customPageUnAuth(Page<CommentDO> page, String type, Long sourceId, Long parentId,String sort) {
        LambdaQueryWrapper<CommentDO> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(oConvertUtils.isNotEmpty(type),CommentDO::getType,type);
        lambdaQueryWrapper.eq(oConvertUtils.isNotEmpty(sourceId),CommentDO::getSourceId,sourceId);
        lambdaQueryWrapper.eq(oConvertUtils.isNotEmpty(parentId),CommentDO::getParentId,parentId);
        lambdaQueryWrapper.isNull(oConvertUtils.isEmpty(parentId),CommentDO::getParentId);
        lambdaQueryWrapper.eq(oConvertUtils.isNotEmpty(parentId),CommentDO::getParentId,parentId);

        return baseMapper.customPage(page,lambdaQueryWrapper,sort);
    }
    /**
     * 点赞
     *
     * @param commentId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void like(Long commentId) {
        UserDO userDO=(UserDO) SecurityUtils.getSubject().getPrincipal();
        //查看是否已经点赞，不为空走点赞逻辑，为空走取消点赞逻辑
        CommentLikeRecordDO commentLikeRecordDO=commentLikeRecordDOService.getByUserIdCommentId(commentId,userDO.getId());
        if(commentLikeRecordDO!=null){
            //删除点赞记录
            if(!commentLikeRecordDOService.removeById(commentLikeRecordDO.getId())){
                throw new BusinessException(ExceptionEnums.SYSTEM_ERROR);
            }
            //同步评论点赞数
            if(baseMapper.decrLike(commentId)<1){
                throw new BusinessException(ExceptionEnums.SYSTEM_ERROR);
            }
        }else{
            //添加点赞记录
            commentLikeRecordDO=new CommentLikeRecordDO();
            commentLikeRecordDO.setCommentId(commentId);
            commentLikeRecordDO.setUserId(userDO.getId());
           if(! commentLikeRecordDOService.save(commentLikeRecordDO)){
               throw new BusinessException(ExceptionEnums.SYSTEM_ERROR);
           }
            //同步评论点赞数
            if(baseMapper.incrLike(commentId)<1){
                throw new BusinessException(ExceptionEnums.SYSTEM_ERROR);
            }

        }
    }
    /**
     * 评论数量统计
     *
     * @param type
     * @param sourceId
     * @return
     */
    @Override
    public Long commentTotal(Long sourceId, String type) {
        return Long.valueOf(baseMapper.selectCount(new LambdaQueryWrapper<CommentDO>().eq(CommentDO::getType,type).eq(CommentDO::getSourceId,sourceId)));
    }
}
